﻿// ===============================================================================
// WebContext.cs
// WelcomeBox Web Framework - Demo
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace NewsDemo
{
    using System;
    using System.Web;
    using EOS.Framework.Kernel;
    using NewsDemo.Data;

    public sealed class WebContext
    {
        public const string LogoutQuery = "?Logout=true";

        private const string AuthentificationCookiePasswordKey = "EOSNDPSW";
        private const string AuthentificationCookieUsernameKey = "EOSNDUSN";

        private static volatile WebContext instance;
        private static object syncRoot = new Object();

        private WebContext() { }

        public static WebContext Current
        {
            get 
            {
                if (instance == null) 
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new WebContext();
                        }
                    }
                }

                return instance;
            }
        }

        public bool LoggedOut
        {
            get
            {
                object loggedOutState = HttpContext.Current.Session["LoggedOut"];
                return loggedOutState == null ? false : (bool)loggedOutState;
            }
        }

        public Editor Editor
        {
            get
            {
                Editor editor = null;
                if (HttpContext.Current.Session != null)
                {
                    editor = HttpContext.Current.Session["LoggedInUser"] as Editor;
                }
                return editor;
            }
        }

        /// <summary>
        /// Meldet den Benutzer ab.
        /// </summary>
        public void Logout()
        {
            HttpContext.Current.Session["LoggedInUser"] = null;

            HttpCookie passwordCookie = HttpContext.Current.Request.Cookies[AuthentificationCookiePasswordKey];
            if (passwordCookie != null)
            {
                passwordCookie.Value = string.Empty;
            }

            HttpCookie usernameCookie = HttpContext.Current.Request.Cookies[AuthentificationCookieUsernameKey];
            if (usernameCookie != null)
            {
                usernameCookie.Value = string.Empty;
            }

            HttpContext.Current.Session["LoggedOut"] = true;
        }

        public void Login(Editor editor, bool saveData)
        {
            if (editor == null)
            {
                throw new ArgumentException("editor");
            }

            HttpContext.Current.Session["LoggedInUser"] = editor;
            HttpContext.Current.Session["LoggedOut"] = false;
            
            if (saveData)
            {
                HttpCookie passwordCookie = new HttpCookie(AuthentificationCookiePasswordKey);
                passwordCookie.Value = editor.Password;
                passwordCookie.Expires = DateTime.Now.AddDays(30);

                HttpContext.Current.Response.Cookies.Add(passwordCookie);

                HttpCookie usernameCookie = new HttpCookie(AuthentificationCookieUsernameKey);
                usernameCookie.Value = editor.Username;
                usernameCookie.Expires = DateTime.Now.AddDays(30);

                HttpContext.Current.Response.Cookies.Add(usernameCookie);
            }
        }

        /// <summary>
        /// Überprüft, ob es Cookie Daten gibt und der Benutzer automatisch angemeldet werden kann,
        /// oder ob der Benutzer ausgeloggt werden soll.
        /// </summary>
        public void StartUpAuthentication()
        {
            HttpCookieCollection cookies = HttpContext.Current.Request.Cookies;

            string password = null, username = null;

            if (Editor == null && !LoggedOut)
            {
                HttpCookie passwordCookie = HttpContext.Current.Request.Cookies[AuthentificationCookiePasswordKey];
                if (passwordCookie != null)
                {
                    password = passwordCookie.Value;
                }

                HttpCookie usernameCookie = HttpContext.Current.Request.Cookies[AuthentificationCookieUsernameKey];
                if (usernameCookie != null)
                {
                    username = usernameCookie.Value;
                }

                if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
                {
                    Editor editor = Unity.Current.Resolve<IEditorDao>().FindByNameAndPassword(username, password);
                    if (editor != null)
                    {
                        Login(editor, true);
                    }
                }
            }

            if (HttpContext.Current.Request.Url.PathAndQuery.Contains(LogoutQuery))
            {
                // Logout if the url contains the logout query string.
                Logout();
            }
        }
    }
}
